package com.service.order.impl;

import com.action.pc.order.OrderDetailVo;
import com.action.pc.order.OrderProductVo;
import com.action.wx.order.AddressVo;
import com.action.wx.order.OrderVo;
import com.action.wx.order.ProductVo;
import com.alibaba.fastjson.JSONObject;
import com.bean.*;
import com.common.ModelAndJson;
import com.common.SystemConfig;
import com.dao.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.service.order.OrderService;
import com.util.Config;
import com.util.HttpClient;
import com.util.IdGenerator;
import com.util.StringUtil;
import com.util.wxpay.WxUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by lvjianqing on 2017/9/10.
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private Order_infoMapper order_infoMapper;
    @Autowired
    private Address_bookMapper address_bookMapper;

    @Autowired
    private Order_payMapper order_payMapper;

    @Autowired
    private Order_productMapper order_productMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private Mb_accountMapper mb_accountMapper;

    @Autowired
    private Integral_recordMapper integral_recordMapper;

    @Autowired
    private Prop_configMapper prop_configMapper;

    @Autowired
    private Rebate_recordMapper rebate_recordMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private Wx_configMapper wx_configMapper;

    @Autowired
    private Balance_recordMapper balance_recordMapper;

    @Override
    public Page findByPage(int pageNum, int pageSize, HashMap<String, Object> paraMap) {
        PageHelper.startPage(pageNum, pageSize);
        Page page = (Page) order_infoMapper.findAll(paraMap);
        return page;
    }

    @Override
    public Order_info findOrderById(Integer id) {
        if (id != null) {
            return order_infoMapper.selectByPrimaryKey(id);
        }
        return null;
    }

    @Override
    public ModelAndJson  createOrder(OrderVo od) {
        ModelAndJson result = new ModelAndJson();
        Order_info order=orderTrsfor(od);
        /*常规订单创建*/
        if(od.getOrderType()==4||od.getOrderType()==1){
            result= newRoutineOrder(od,order);
        }
        //充值订单
        if(od.getOrderType()==2){
            result=newChargeOrder(od,order);
        }
        //收款订单
        if(od.getOrderType()==3){
            result=newQrcodeOrder(od,order);
        }
        return result;
    }

    /**
     * 创建充值订单
     * @param od
     * @param order
     * @return
     */
    public  ModelAndJson newChargeOrder(OrderVo od,Order_info order){
        ModelAndJson result = new ModelAndJson();
        String orderNo=IdGenerator.getOrderNo("");
        order.setOrderno(orderNo);
        order.setOrderstatus(0);
        order_infoMapper.insert(order);

        Order_pay opay=new Order_pay();
        opay.setOrderno(orderNo);
        opay.setPayamount(order.getPayamount());
        opay.setPaytype(od.getPayType());
        opay.setStatus((byte) 0);
        order_payMapper.insert(opay);
        result.put("orderNo",orderNo);
        result.setTrue("");

        return result;
    }

    /**
     * 创建收款订单
     * @param od
     * @param order
     * @return
     */
    public  ModelAndJson newQrcodeOrder(OrderVo od,Order_info order){
        ModelAndJson result = new ModelAndJson();
        String orderNo=IdGenerator.getOrderNo("");
        if(od.getPayType()==2||od.getPayType()==3){
            Integer mid = od.getMemberId();
            Mb_account mb = mb_accountMapper.selectByMemberId(mid);
            if(od.getPayType()==2){
                if(!validBalance(order,mb)){
                    result.setFalse("error","账户余额不足");
                    return  result;
                }
                this.balanceChange(order.getCityid(),od.getMemberId(),order.getAmount(),orderNo,(byte)6,(byte)0);
            }
            if(od.getPayType()==3){
                if(!validIntegral(order,mb)){
                    result.setFalse("error","积分余额不足");
                    return  result;
                }
                /*消费积分*/
                this.integralChange(od.getCityId(),od.getMemberId(),order.getAmount().intValue(),orderNo,(byte)3,(byte)0);
            }
        }

        order.setOrderno(orderNo);
        if(od.getPayType()==2||od.getPayType()==3) {
            order.setOrderstatus(1);
        }else if(od.getPayType()==1){
            order.setOrderstatus(0);
        }
        order_infoMapper.insert(order);

        Order_pay opay=new Order_pay();
        opay.setOrderno(orderNo);
        opay.setPayamount(order.getPayamount());
        opay.setPaytype(od.getPayType());
        if(od.getPayType()==2||od.getPayType()==3) {
            opay.setStatus((byte) 1);
        }else if(od.getPayType()==1){
            opay.setStatus((byte) 0);
        }
        order_payMapper.insert(opay);

        result.put("orderNo",orderNo);
        result.setTrue("");

        return result;
    }
    /**
     * 创建常规订单
     * @param od
     * @param order
     * @return
     */
    public  ModelAndJson newRoutineOrder(OrderVo od,Order_info order){
        ModelAndJson result = new ModelAndJson();
        String orderNo=IdGenerator.getOrderNo("");
        if(!validAmount(order,od.getProList())){
            result.setFalse("error","订单金额校验失败");
            return  result;
        }
        //支付方式  1表示微信支付 2 表示余额支付 3 表示积分支付
        if(od.getPayType()==2||od.getPayType()==3){
            Integer mid = od.getMemberId();
            Mb_account mb = mb_accountMapper.selectByMemberId(mid);
            if(od.getPayType()==2){
                if(!validBalance(order,mb)){
                    result.setFalse("error","账户余额不足");
                    return  result;
                }
                this.balanceChange(order.getCityid(),od.getMemberId(),order.getAmount(),orderNo,(byte)6,(byte)0);
            }
            if(od.getPayType()==3){
                if(!validIntegral(order,mb)){
                    result.setFalse("error","积分余额不足");
                    return  result;
                }
                /*消费积分*/
                this.integralChange(od.getCityId(),od.getMemberId(),order.getAmount().intValue(),orderNo,(byte)3,(byte)0);
            }
        }
        order.setOrderno(orderNo);
        if(od.getPayType()==2||od.getPayType()==3) {
            order.setOrderstatus(1);
        }else if(od.getPayType()==1){
            order.setOrderstatus(0);
        }
        order_infoMapper.insert(order);

        Order_pay opay=new Order_pay();
        opay.setOrderno(orderNo);
        opay.setPayamount(order.getPayamount());
        opay.setPaytype(od.getPayType());
        if(od.getPayType()==2||od.getPayType()==3) {
            opay.setStatus((byte) 1);
        }else if(od.getPayType()==1){
            opay.setStatus((byte) 0);
        }
        order_payMapper.insert(opay);
        List<ProductVo> proList = od.getProList();
        for (ProductVo pro:proList){
            Order_product op=new Order_product();
            op.setOrderno(orderNo);
            op.setPrice(pro.getPrice());
            op.setProductid(pro.getId());
            op.setProductimg(pro.getCoverimg());
            op.setProductnum(pro.getProNum());
            order_productMapper.insert(op);
        }
        result.put("orderNo",orderNo);
        result.setTrue("");
        return result;
    }

    /**
     * 订单对象转换
     * @param order
     * @return
     */
    public Order_info orderTrsfor(OrderVo order){
        Order_info result=new Order_info();
        Integer addrId = order.getAbId();
        AddressVo addrVo = address_bookMapper.selectById(addrId);
        if(addrVo!=null){
            result.setAddr(addrVo.getAddr());
            result.setCityname(addrVo.getCityName());
            result.setDisname(addrVo.getRealname());
            result.setDistel(addrVo.getTel());
            result.setProvincename(addrVo.getProvinceName());
            result.setRegionname(addrVo.getRegionName());
        }
        result.setAmount(order.getTotalAmount());
        result.setPayamount(order.getTotalAmount());
        result.setCityid(order.getCityId());
        result.setCreatetime(new Date());
        result.setDisamount(new BigDecimal(0));
        result.setMemberid(order.getMemberId());
        result.setOrdertype(order.getOrderType());
        result.setRemark(order.getRemark());
        return  result;
    }

    /**
     * 校验订单金额
     * @param od
     * @param proList
     * @return
     */
    public boolean validAmount(Order_info od,List<ProductVo> proList){
        BigDecimal proAmount = new BigDecimal(0);
        for(ProductVo pro:proList){
            proAmount=proAmount.add(pro.getPrice());
        }
        if(proAmount.doubleValue()!=od.getAmount().doubleValue()){
            return false;
        }
        return true;
    }

    public boolean validIntegral(Order_info od,Mb_account mb){
        BigDecimal payAmount = od.getAmount();
        if(mb.getIntegral()-payAmount.intValue()<0){
            return false;
        }
        return true;
    }
    public boolean validBalance(Order_info od,Mb_account mb){
        BigDecimal payAmount = od.getAmount();
        if(mb.getBalance().doubleValue()-payAmount.doubleValue()<0){
            return false;
        }
        return true;
    }


    @Override
    public Order_info findByOrderNo(String orderNo) {
        return order_infoMapper.findByOrderNo(orderNo);
    }

    @Override
    public void callBack(String orderNo) {
        Order_info order = order_infoMapper.findByOrderNo(orderNo);
        /*只处理未支付订单*/
        if(order.getOrderstatus()!=0){
            return;
        }
            Order_pay orderPay = order_payMapper.selectByOrderNo(orderNo);
            orderPay.setPaytime(new Date());
            orderPay.setStatus((byte)1);
            order_payMapper.updateByPrimaryKey(orderPay);

            /*处理常规订单*/
            if(order.getOrdertype()==1){
                order.setOrderstatus(1);
                order_infoMapper.updateByPrimaryKey(order);
            }

            /*处理充值订单*/
            if(order.getOrdertype()==2){
                order.setOrderstatus(1);
                order_infoMapper.updateByPrimaryKey(order);
                this.balanceChange(order.getCityid(),order.getMemberid(),order.getAmount(),orderNo,(byte)1,(byte)1);
            }

            /*处理合作商收款订单*/
            if(order.getOrdertype()==3){

            }
            /*处理引流订单*/
            if(order.getOrdertype()==4){
                order.setOrderstatus(1);
                order_infoMapper.updateByPrimaryKey(order);
                Integer memberId = order.getMemberid();
                Member member = memberMapper.selectByPrimaryKey(memberId);
                if(member.getIsactive()==0){
                    /*激活会员*/
                    member.setIsactive((byte)1);
                    memberMapper.updateByPrimaryKey(member);
                    /*处理积分账户数据 开始*/
                    String sendInteger=Config.getString("register.integral");//入会赠送积分
                    integralChange(order.getCityid(),order.getMemberid(),Integer.parseInt(sendInteger),orderNo,(byte)1,(byte)1);/*添加积分变动记录*/
                    /*处理积分账户数据 结束*/
                    String sendMsg=Config.getString("reg.msg");
                    this.sendWxMsg(member.getOpenid(),sendMsg);
                }
                if(member.getParentid()!=null){
                        /*处理上下级返利*/
                    this.doRebate(member,order,(byte)1);
                }
            }
    }

    /**
     * 添加积分变动记录
     * @param cityId
     * @param memberId
     * @param integral
     * @param orderNo
     * @param type
     */
    public void integralChange(Integer cityId,Integer memberId,Integer integral,String orderNo,Byte type,Byte income){
        Mb_account mb = new Mb_account();
        mb.setMemberid(memberId);
        mb.setIntegral(integral);
        if(income==1){
            mb_accountMapper.updateAccountPlusByMemberid(mb);
        }else{
            mb_accountMapper.updateAccountSubtractByMemberid(mb);
        }

        Integral_record record=new Integral_record();
        record.setCityid(cityId);
        record.setCreatetime(new Date());
        record.setMemberid(memberId);
        record.setNum(integral);
        record.setOrderno(orderNo);
        record.setType(type);//1-入会赠送
        record.setIncome(income);//1-入账;0-出账
        integral_recordMapper.insert(record);
    }

    /**
     * 佣金变动记录
     * @param cityId
     * @param memberId
     * @param rebate
     * @param orderNo
     * @param type
     * @param income
     */
    public void rebateChange(Integer cityId,Integer memberId,BigDecimal rebate,String orderNo,Byte type,Byte income,Byte lv){
        Mb_account mb = new Mb_account();
        mb.setMemberid(memberId);
        mb.setRebate(rebate);
        if(income==1){
            mb_accountMapper.updateAccountPlusByMemberid(mb);
        }else{
            mb_accountMapper.updateAccountSubtractByMemberid(mb);
        }

        Rebate_record record=new Rebate_record();
        record.setCityid(cityId);
        record.setCreatetime(new Date());
        record.setMemberid(memberId);
        record.setLv(lv);
        record.setAmount(rebate);
        record.setOrderno(orderNo);
        record.setType(type);//1-返利
        record.setIncome(income);//1-入账;0-出账
        rebate_recordMapper.insert(record);
    }

    //增加交易记录
    public void balanceChange(Integer cityId,Integer memberId,BigDecimal amount,String orderNo,Byte type,Byte income){
        Mb_account mb = new Mb_account();
        mb.setMemberid(memberId);
        mb.setBalance(amount);
        if(income==1){
            mb_accountMapper.updateAccountPlusByMemberid(mb);
        }else{
            mb_accountMapper.updateAccountSubtractByMemberid(mb);
        }

        Balance_record record=new Balance_record();
        record.setCityid(cityId);
        record.setCreatetime(new Date());
        record.setMemberid(memberId);
        record.setAmount(amount);
        record.setOrderno(orderNo);
        record.setType(type);//1-充值;2-购买商品;3-提现申请中;4-提现成功;5-提现未成功;6-合作商消费
        record.setIncome(income);//1-入账;0-出账
        balance_recordMapper.insert(record);
    }


    /**
     * 处理返利业务
     * @param member
     * @param order
     * @param type 1-处理引流订单业务；2-处理常规订单业务
     */
    public void doRebate(Member member,Order_info order,Byte type){
        Integer cityId = order.getCityid();
        Integer fpid=member.getParentid();
        Member fm = memberMapper.selectByPrimaryKey(fpid);
        Prop_config config = prop_configMapper.findByCityid(cityId);
        if(type==1){
            this.rebateChange(order.getCityid(),member.getId(),config.getFirstpush(),order.getOrderno(),type,(byte)1,(byte)1);
            String sendMsg=Config.getString("rebate.msg");
            sendMsg=sendMsg.replace("@NICKNAME",member.getNickname()).replace("@AMOUNT",order.getAmount().toString()).replace("@LV","1").replace("@REBATE",config.getFirstpush().toString());
            this.sendWxMsg(fm.getOpenid(),sendMsg);
            if(fm.getParentid()!=null){
                Integer spid = fm.getParentid();
                Member sm = memberMapper.selectByPrimaryKey(fpid);
                this.rebateChange(order.getCityid(),member.getId(),config.getSecondpush(),order.getOrderno(),type,(byte)1,(byte)2);
                sendMsg=Config.getString("rebate.msg");
                sendMsg=sendMsg.replace("@NICKNAME",member.getNickname()).replace("@AMOUNT",order.getAmount().toString()).replace("@LV","2").replace("@REBATE",config.getSecondpush().toString());
                this.sendWxMsg(fm.getOpenid(),sendMsg);
            }
        }
    }

    /**
     * 发送微信推送消息
     * @param openId
     * @param content
     * @return
     */
    @Override
    public  boolean sendWxMsg(String openId, String content) {
        Integer id=Config.getInt("wx.configid");
        Wx_config config = wx_configMapper.selectByPrimaryKey(id);
        String accessToken="";
        String appId=config.getAppid();
        String appSecret=config.getAppsecret();
        if(!this.isNeedUpdateToken(config)){
            System.out.println("数据库token");
            accessToken= config.getAccesstoken();
        }else{
            System.out.println("接口token");
            accessToken = this.getAccessToken(appId, appSecret);
        }
        String url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN";
        url=url.replace("ACCESS_TOKEN", accessToken);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", openId);//发送对象
        jsonObject.put("msgtype", "text");//消息类型

        JSONObject jsob=new JSONObject();
        jsob.put("content", content);

        jsonObject.put("text", jsob);
        String json=jsonObject.toString();
        System.out.println(json);
        JSONObject jt = HttpClient.httpRequest(url, "POST", json);
        System.out.println(jt);
        return true;
    }


    public boolean isNeedUpdateToken(Wx_config wechat){
        Date lastUpdateTime=wechat.getTokentime();
        if(lastUpdateTime==null){
            return true;
        }
        long oldTimesMillis=lastUpdateTime.getTime();
        long newTimesMillis=new Date().getTime();
        if(newTimesMillis-oldTimesMillis>3600*1000){
            return true;
        }else{
            return false;
        }
    }

    public String getAccessToken(String appId, String appSecret) {
        Integer id=Config.getInt("wx.configid");
        Wx_config config = wx_configMapper.selectByPrimaryKey(id);
        String accessToken="";
        if(!this.isNeedUpdateToken(config)){
            System.out.println("数据库token");
            accessToken= config.getAccesstoken();
            return  accessToken;
        }
        String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        url=url.replace("APPID", appId);
        url=url.replace("APPSECRET", appSecret);
        String result= HttpClient.get(url);
        JSONObject jsonObject= JSONObject.parseObject(result);
        accessToken=(String)jsonObject.get("access_token");
        config.setAccesstoken(accessToken);
        config.setTokentime(new Date());
        wx_configMapper.updateByPrimaryKey(config);
        return accessToken;
    }

    @Override
    public Order_info saveSend(Order_info order) {
        if (order != null && order.getOrderstatus() == 1) {//已支付
            order.setOrderstatus(2);//设置为已发货
            order_infoMapper.updateByPrimaryKeySelective(order);
        }else if (order != null && order.getOrderstatus() == 2) {//已发货
            order_infoMapper.updateByPrimaryKeySelective(order);
        }
        return order;
    }

    @Override
    public Order_info saveBack(Order_info order) {
        if(order != null){
            if (order.getOrderstatus() == 5) {
                order.setOrderstatus(7);
                order_infoMapper.updateByPrimaryKeySelective(order);
            }else if (order.getOrderstatus() == 6) {
                order.setOrderstatus(8);
                order_infoMapper.updateByPrimaryKeySelective(order);
            }
            Mb_account account = new Mb_account();
            account.setMemberid(order.getMemberid());
            account.setIntegral(order.getIntegral());
            account.setBalance(order.getPayamount());
            mb_accountMapper.updateAccountPlusByMemberid(account);
        }
        return order;
    }

    @Override
    public Map countOrder(HashMap<String, Object> paraMap) {
        return order_infoMapper.findSumAmount(paraMap);
    }

    @Override
    public Page findMemberOrdersByPage(int pageNum, int pageSize, HashMap<String, Object> paraMap) {
        PageHelper.startPage(pageNum, pageSize);
        List<OrderDetailVo> orderList = order_infoMapper.findMemberOrdersByPage(paraMap);
        for (OrderDetailVo vo:orderList){
            List<OrderProductVo> opList = this.getOrderProductByOrderNo(vo.getOrderno());
            vo.setOpList(opList);
            Order_pay opay = order_payMapper.selectByOrderNo(vo.getOrderno());
            BeanUtils.copyProperties(opay,vo);
        }
        return (Page)orderList;
    }

    @Override
    public List<OrderProductVo> getOrderProductByOrderNo(String orderNo) {
        if(StringUtil.isEmpty(orderNo)){
            return new ArrayList<OrderProductVo>();
        }
        List<Order_product> opList=order_productMapper.selectByOrderNo(orderNo);
        ArrayList<OrderProductVo> result = new ArrayList<OrderProductVo>();
        for(Order_product op:opList){
            OrderProductVo vo=new OrderProductVo();
            BeanUtils.copyProperties(op,vo);
            Integer pid = op.getProductid();
            Product pro = productMapper.selectByPrimaryKey(pid);
            vo.setSmimg(pro.getSmimg());
            vo.setOldprice(pro.getOldprice());
            vo.setProname(pro.getProname());
            vo.setShortname(pro.getShortname());
            result.add(vo);
        }
        return result;
    }
}
